package model

import (
	"database/sql"
	"fmt"
	"time"
	"wxpay/pkg/util"
)

/*
DB Table Details
-------------------------------------


Table: transfer_detail
[ 0] id                                             INT8                 null: false  primary: true   isArray: false  auto: false  col: INT8            len: -1      default: []
[ 1] out_detail_no                                  VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 2] biz_detail_no                                  VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 3] amount                                         INT8                 null: false  primary: false  isArray: false  auto: false  col: INT8            len: -1      default: []
[ 4] remark                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 5] open_id                                        VARCHAR(128)         null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 128     default: []
[ 6] user_name                                      VARCHAR(255)         null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
[ 7] user_id_card                                   VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
[ 8] status                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[ 9] fail_reason                                    VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
[10] initiate_time                                  TIMESTAMPTZ          null: true   primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
[11] create_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
[12] update_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
[13] app_id                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[14] out_batch_no                                   VARCHAR(32)          null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
[15] mch_id                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []


JSON Sample
-------------------------------------
{    "id": 43,    "biz_detail_no": "fprcueGHrAutgcfGtGqmXWIZm",    "amount": 37,    "open_id": "FuENHfXbfxdinmShFFTeIxdop",    "status": "toTnOqEyQVWRlSCxhsJmiPSXu",    "initiate_time": "2160-04-26T10:12:27.890491438+08:00",    "app_id": "vNwBdDOSAAjOfDKyNDNEecajN",    "out_batch_no": "ciJUOVJGtldqrWTaTxVQnuXqn",    "mch_id": "kyfvNgRcgMXBQoWlIuuawmJIQ",    "out_detail_no": "bhMWReNurgxcvIWWWkXypmWdb",    "remark": "DjjZGaKtIcXXXyretAIhENubL",    "user_id_card": "vHbMpiqEZEXhObELWsPBQeaou",    "create_time": "2158-08-17T14:17:21.85999699+08:00",    "user_name": "JodRmgOiHHyexLtXsHidqPDHf",    "fail_reason": "HnYBTInSZtxGYCkApfnjWRZGb",    "update_time": "2139-12-03T21:15:21.553092734+08:00"}



*/

// TransferDetail struct is a row record of the transfer_detail table in the wxpay database
type TransferDetail struct {
	//[ 0] id                                             INT8                 null: false  primary: true   isArray: false  auto: false  col: INT8            len: -1      default: []
	ID int64 `gorm:"primary_key;column:id;type:INT8;"`
	//[ 1] out_detail_no                                  VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	OutDetailNo string `gorm:"column:out_detail_no;type:VARCHAR;size:32;"`
	//[ 2] biz_detail_no                                  VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	BizDetailNo string `gorm:"column:biz_detail_no;type:VARCHAR;size:32;"`
	//[ 3] amount                                         INT8                 null: false  primary: false  isArray: false  auto: false  col: INT8            len: -1      default: []
	Amount int64 `gorm:"column:amount;type:INT8;"`
	//[ 4] remark                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	Remark string `gorm:"column:remark;type:VARCHAR;size:32;"`
	//[ 5] open_id                                        VARCHAR(128)         null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 128     default: []
	OpenID string `gorm:"column:open_id;type:VARCHAR;size:128;"`
	//[ 6] user_name                                      VARCHAR(255)         null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
	UserName string `gorm:"column:user_name;type:VARCHAR;size:255;"`
	//[ 7] user_id_card                                   VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
	UserIDCard sql.NullString `gorm:"column:user_id_card;type:VARCHAR;size:255;"`
	//[ 8] status                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	Status string `gorm:"column:status;type:VARCHAR;size:32;"`
	//[ 9] fail_reason                                    VARCHAR(255)         null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 255     default: []
	FailReason sql.NullString `gorm:"column:fail_reason;type:VARCHAR;size:255;"`
	//[10] initiate_time                                  TIMESTAMPTZ          null: true   primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
	InitiateTime *time.Time `gorm:"column:initiate_time;type:TIMESTAMPTZ;"`
	//[11] create_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
	CreateTime time.Time `gorm:"column:create_time;type:TIMESTAMPTZ;"`
	//[12] update_time                                    TIMESTAMPTZ          null: false  primary: false  isArray: false  auto: false  col: TIMESTAMPTZ     len: -1      default: []
	UpdateTime time.Time `gorm:"column:update_time;type:TIMESTAMPTZ;"`
	//[13] app_id                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	AppID string `gorm:"column:app_id;type:VARCHAR;size:32;"`
	//[14] out_batch_no                                   VARCHAR(32)          null: true   primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	OutBatchNo sql.NullString `gorm:"column:out_batch_no;type:VARCHAR;size:32;"`
	//[15] mch_id                                         VARCHAR(32)          null: false  primary: false  isArray: false  auto: false  col: VARCHAR         len: 32      default: []
	MchID      string `gorm:"column:mch_id;type:VARCHAR;size:32;"`
	BatchGroup string `gorm:"column:batch_group;type:VARCHAR;size:16;"`
}

// TableName sets the insert table name for this struct type
func (t *TransferDetail) TableName() string {
	return "transfer_detail"
}

const DetailStatusAwait string = "AWAIT"
const DetailStatusProcessing string = "PROCESSING"
const DetailStatusSuccess string = "SUCCESS"
const DetailStatusFAIL string = "FAIL"

// 根据时间生成时间批次,每15分钟生成一个批次，一天共有96个批次 格式为2020010200~2020010295
func GenBatchGroup(n time.Time) (batchGroup string) {
	return fmt.Sprintf("%s%02d", n.Format(util.LayoutYYMMdd), n.Hour()*4+(n.Minute()/15))
}

func (t *TransferDetail) Initialize() {
	n := util.GetNow()
	t.OutDetailNo = fmt.Sprintf("TD%s%s", n.Format(util.LayoutYYMMdd), util.RandString(6))
	t.Status = DetailStatusAwait
	t.BatchGroup = GenBatchGroup(n)
	t.CreateTime = n
	t.UpdateTime = n
}

// 更新批次号
func (t *TransferDetail) UpdateOutBatchNo(batchNo string) {
	t.OutBatchNo = util.AdaptNullString(batchNo)
	t.Status = DetailStatusProcessing
	t.UpdateTime = util.GetNow()
}

// 更新转账结果 - 状态、发起转账时间、失败原因
func (t *TransferDetail) UpdateResult(td *TransferDetail) {
	t.Status = td.Status
	if t.InitiateTime == nil && td.InitiateTime != nil {
		t.InitiateTime = td.InitiateTime
	}
	if !t.FailReason.Valid && td.FailReason.Valid {
		t.FailReason = td.FailReason
	}
	t.UpdateTime = util.GetNow()
}
